package com.gitee.wsl.doc.prosemirror.ui.command

import com.gitee.wsl.doc.prosemirror.model.content.ext.findCutAfter
import com.gitee.wsl.doc.prosemirror.model.fragment.Slice
import com.gitee.wsl.doc.prosemirror.model.node.ext.TextblockSide
import com.gitee.wsl.doc.prosemirror.model.node.ext.textblockAt
import com.gitee.wsl.doc.prosemirror.state.Command
import com.gitee.wsl.doc.prosemirror.state.CommandDispatch
import com.gitee.wsl.doc.prosemirror.state.EditorState
import com.gitee.wsl.doc.prosemirror.state.Transaction
import com.gitee.wsl.doc.prosemirror.state.ext.deleteBarrier
import com.gitee.wsl.doc.prosemirror.state.selection.NodeSelection
import com.gitee.wsl.doc.prosemirror.state.selection.Selection
import com.gitee.wsl.doc.prosemirror.transform.ext.delete
import com.gitee.wsl.doc.prosemirror.transform.ext.replaceStep
import com.gitee.wsl.doc.prosemirror.transform.ext.step
import com.gitee.wsl.doc.prosemirror.transform.step.ReplaceStep
import com.gitee.wsl.doc.prosemirror.ui.EditorView
import com.gitee.wsl.doc.prosemirror.ui.ext.atBlockEnd


object JoinForward:UiCommand {
    override fun exec(
        view: EditorView?,
        state: EditorState,
        dispatch: CommandDispatch?,
    ): Boolean {
        val cursor = atBlockEnd(state, view)
        if (cursor == null) return false

        val cut = cursor.findCutAfter()
        if (cut == null) return false

        val after = cut.nodeAfter!!

        // 尝试删除边界
        if (state.deleteBarrier(cut, dispatch, 1)) {
            return true
        }

        // 如果当前节点内容为空且下一个节点可选择，则删除当前节点并选择下一个节点
        if (cursor.parent.content.size == 0 &&
            (after.textblockAt( TextblockSide.start) || NodeSelection.isSelectable(after))) {
            val delStep = state.doc.replaceStep( cursor.before(), cursor.after(), Slice.empty) as ReplaceStep?
            if (delStep != null && delStep.slice.size < delStep.to - delStep.from) {
                if (dispatch != null) {
                    val tr = state.tr.step(delStep)
                    val selection = if (after.textblockAt( TextblockSide.start)) {
                        Selection.findFrom(tr.doc.resolve(tr.mapping.map(cut.pos)), 1)
                    } else {
                        NodeSelection.create(tr.doc, tr.mapping.map(cut.pos))
                    }
                    tr.setSelection(selection!!)
                    dispatch(tr.scrollIntoView())
                }
                return true
            }
        }

        // 如果下一个节点是原子节点且深度合适，则删除它
        if (after.isAtom && cut.depth == cursor.depth - 1) {
            if (dispatch != null) {
                dispatch(state.tr.delete(cut.pos, cut.pos + after.nodeSize).scrollIntoView())
            }
            return true
        }

        return false
    }
}

/**
 * 尝试在光标位置后合并或调整文本块边界
 */
val Command.Companion.joinForward
    get() = JoinForward